package com.hlkj.pay.controller.pay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
/**
 * @author HlpayTeam
 * @date 2024/09/25 9:54
 */
public class ThirdDictListener extends AnalysisEventListener<ThirdLevelDict> {
	private static final Logger LOGGER = LoggerFactory.getLogger(ThirdDictListener.class);
	/**
	 * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
	 */
	private static final int BATCH_COUNT = 5;
	List<ThirdLevelDict> list = new ArrayList<>();
	
	private String channelCode;
	private String dictKey;
	/**
	 * 假设这个是一个DAO，当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
	 */
	
	public ThirdDictListener(String channelCode,String dictKey) {
		this.channelCode = channelCode;
		this.dictKey = dictKey;
	}
	
	
	/**
	 * 这个每一条数据解析都会来调用
	 *
	 * @param data
	 *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}
	 * @param context
	 */
	@Override
	public void invoke(ThirdLevelDict data, AnalysisContext context) {
		// LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
		list.add(data);
		// 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
		if (list.size() >= BATCH_COUNT) {
			// processSql();
			// 存储完成清理 list
			// list.clear();
		}
	}
	
	/**
	 * 所有数据解析完成了 都会来调用
	 *
	 * @param context
	 */
	@Override
	public void doAfterAllAnalysed(AnalysisContext context) {
		// 这里也要保存数据，确保最后遗留的数据也存储到数据库
		LOGGER.info("所有数据解析完成！");
		processSql();
	}
	public void processSql(){
		Set<String> parentDictSql=new HashSet<>();
		Set<String> secondDictSql=new HashSet<>();
		Set<String> thirdDictSql=new HashSet<>();
		Map<String, List<ThirdLevelDict>> parentDict = list.stream()
				.collect(Collectors.groupingBy(secondLevelDict -> secondLevelDict.getParentDictName()));
		AtomicReference<Integer> parentValue= new AtomicReference<>(0);
		parentDict.forEach((parentKey,parentValueList)->{
			AtomicReference<Integer> secondDictValue= new AtomicReference<>(0);
			//一级
			ThirdLevelDict parentLevelDict = parentValueList.get(0);
			if(!StringUtils.hasText(parentLevelDict.getParentDictValue())){
				System.out.println("vue 1级为空"+parentLevelDict.getParentDictName());
				parentLevelDict.setParentDictValue(String.format("%02d", parentValue.get() + 1));
				parentValue.set(parentValue.get() + 1);
			}
			
			StringBuilder parentSb=new StringBuilder("insert into t_pay_channel_dict(channel_code,dict_key,dict_level,dict_value,dict_desc,type) value (");
			parentSb.append("'");
			parentSb.append(channelCode);
			parentSb.append("','");
			parentSb.append(dictKey);
			parentSb.append("',");
			parentSb.append(1);
			parentSb.append(",'");
			parentSb.append(parentLevelDict.getParentDictValue());
			parentSb.append("','");
			parentSb.append(parentLevelDict.getParentDictName());
			parentSb.append("','");
			parentSb.append(parentLevelDict.getType());
			parentSb.append("');");
			parentDictSql.add(parentSb.toString());
			
			
			Map<String, List<ThirdLevelDict>> secondDict = parentValueList.stream()
					.collect(Collectors.groupingBy(secondLevelDict -> secondLevelDict.getSecondDictName()));
			secondDict.forEach((secondKey,secondValueList)->{
				ThirdLevelDict secondLevelDict = secondValueList.get(0);
				if(!StringUtils.hasText(secondLevelDict.getSecondDictValue())){
					secondLevelDict.setSecondDictValue(parentLevelDict.getParentDictValue()+String.format("%02d", secondDictValue.get() + 1));
					secondDictValue.set(secondDictValue.get() + 1);
				}
				//二级
				StringBuilder secondSb=new StringBuilder("insert into t_pay_channel_dict(channel_code,dict_key,parent_dict_key,dict_level,dict_value,dict_desc,type) value (");
				secondSb.append("'");
				secondSb.append(channelCode);
				secondSb.append("','");
				secondSb.append(dictKey);
				secondSb.append("','");
				secondSb.append(parentLevelDict.getParentDictValue());
				secondSb.append("',");
				secondSb.append(2);
				secondSb.append(",'");
				secondSb.append(secondLevelDict.getSecondDictValue());
				secondSb.append("','");
				secondSb.append(secondLevelDict.getSecondDictName());
				secondSb.append("','");
				secondSb.append(secondLevelDict.getType());
				secondSb.append("');");
				secondDictSql.add(secondSb.toString());
				secondValueList.stream().forEach(thirdDict -> {
					//三级
					StringBuilder thirdSb=new StringBuilder("insert into t_pay_channel_dict(channel_code,dict_key,parent_dict_key,dict_level,dict_value,dict_desc,type) value (");
					thirdSb.append("'");
					thirdSb.append(channelCode);
					thirdSb.append("','");
					thirdSb.append(dictKey);
					thirdSb.append("','");
					thirdSb.append(secondLevelDict.getSecondDictValue());
					thirdSb.append("',");
					thirdSb.append(3);
					thirdSb.append(",'");
					thirdSb.append(thirdDict.getDictValue());
					thirdSb.append("','");
					thirdSb.append(thirdDict.getDictName());
					thirdSb.append("','");
					thirdSb.append(thirdDict.getType());
					thirdSb.append("');");
					thirdDictSql.add(thirdSb.toString());
					//区对应的银行
					if(StringUtils.hasText(thirdDict.getBankCode())){
						//三级
						StringBuilder bankSb=new StringBuilder("insert into t_pay_channel_dict(channel_code,dict_key,parent_dict_key,dict_level,dict_value,dict_desc) value (");
						bankSb.append("'");
						bankSb.append(channelCode);
						bankSb.append("','");
						bankSb.append("bankCityCode");
						bankSb.append("','");
						bankSb.append(thirdDict.getDictValue());
						bankSb.append("',");
						bankSb.append(3);
						bankSb.append(",'");
						bankSb.append(thirdDict.getBankCode());
						bankSb.append("','");
						bankSb.append(thirdDict.getDictName());
						bankSb.append("');");
						thirdDictSql.add(bankSb.toString());
					}
				});
			});
			
			
		});
		
		parentDictSql.stream().forEach(sql->{
			System.out.println(sql);
		});
		secondDictSql.stream().forEach(sql->{
			System.out.println(sql);
		});
		thirdDictSql.stream().forEach(sql->{
			System.out.println(sql);
		});
		
		
	}
}
